/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#include "SBJ/Arrow/Channel.h"
#include "MockMessage.h"

#include <boost/test/auto_unit_test.hpp>

BOOST_AUTO_TEST_CASE(MakeSubscription)
{
	::printf("MakeSubscription\n");
	// Create the channel
	SBJ::Arrow::Channel channel;
	channel.start();

	// Publish our message type
	channel.publish< MockMessage >( "MockMsg" );
	
	MockSubscriber subscriber;
	SBJ::Arrow::Subscription sub1 = channel.makeSubscription< MockMessage >( &subscriber, "MockMsg", "MyTopic" );
	SBJ::Arrow::Subscription sub2 = channel.makeSubscription( &subscriber, "MockMsg", "MyTopic" );

	// Test Likeness
	BOOST_CHECK_EQUAL( true, sub1.isLike( sub2 ) );
}

BOOST_AUTO_TEST_CASE(SubscriptionLife)
{
	::printf("SubscriptionLife\n");
	// Create the channel
	SBJ::Arrow::Channel channel;
	channel.start();

	// Publish our message type
	SBJ::Arrow::Publication& pub = channel.publish< MockMessage >();
	{
		// Subscribe
		MockSubscriber subscriber1;
		SBJ::Arrow::Subscription sub1 = channel.makeTypedSubscription< MockMessage >( &subscriber1, "MyTopic" );
		sub1.activate();

		// Create a dummy
		MockSubscriber subscriber2;
		SBJ::Arrow::Subscription sub2 = channel.makeTypedSubscription< MockMessage >( &subscriber2, "?" );
		sub2.activate();

		// Create the message
		volatile const char* hit = 0;
		MockMessage msg( hit, pub.getTopic< MockMessage >( "MyTopic" ), 0, &subscriber1 );

		// Push the message
		channel.onMessage( msg );

		// And test
		::test_sleep( .5 );
		BOOST_CHECK_EQUAL( MockMessage::hit_dispatch_ToTest, const_cast<char*>(hit) );
	}

	SBJ::Arrow::Topic topic = pub.getTopic< MockMessage >( "MyTopic" );
	BOOST_CHECK_EQUAL( true, !topic.isValid() );
}

BOOST_AUTO_TEST_CASE(SubscriptionAsRemora)
{
	::printf("SubscriptionAsRemora\n");
	// Create the channel
	SBJ::Arrow::Channel channel;
	channel.start();

	// Publish our message type
	SBJ::Arrow::Publication& pub = channel.publish< MockMessage >();
	{
		// Subscribe
		MockSubscriber subscriber;
		SBJ::Arrow::Subscription* sub = new SBJ::Arrow::Subscription(
			channel.makeTypedSubscription< MockMessage >( &subscriber, "MyTopic" ) );
		subscriber.attachRemora( sub );
		sub->activate();

		// Create the message
		volatile const char* hit = 0;
		MockMessage msg( hit, pub.getTopic< MockMessage >( "MyTopic" ), 0, &subscriber );

		// Push the message
		channel.onMessage( msg );

		// And test
		::test_sleep( .5 );
		BOOST_CHECK_EQUAL( MockMessage::hit_dispatch_ToTest, const_cast<char*>(hit) );
	}

	SBJ::Arrow::Topic topic = pub.getTopic< MockMessage >( "MyTopic" );
	BOOST_CHECK_EQUAL( true, !topic.isValid() );
}

